﻿using Engine;
using GameEntitySystem;
using TemplatesDatabase;
using System;
using Engine.Graphics;
using Engine.Input;
using Engine.Media;
using System.Collections.Generic;
using System.Xml.Linq;
using System.Linq;
using System.Globalization;
using Game;

namespace sprintDCmod
{
    public class ComponentSprintDC : Component, IUpdateable
    {
        public ComponentPlayer m_componentPlayer;
        public ComponentLocomotion m_componentLocomotion;
        public ComponentVitalStats ComponentVitalStats => m_componentPlayer.ComponentVitalStats;
        public UpdateOrder UpdateOrder => UpdateOrder.Default;
        public float WalkSpeed;
        public float CreativeFlySpeed;
        public float Speed;
        public bool m_isSprinting;

        public bool m_pressed;
        public bool m_released;

        public double m_lastForwardTime;
        public float m_focalNum;
        public float? FocalOrder;
        private bool m_lastIsSprinting;

		public override void Load(ValuesDictionary valuesDictionary, IdToEntityMap idToEntityMap)
		{
			base.Load(valuesDictionary, idToEntityMap);
            m_componentPlayer = Entity.FindComponent<ComponentPlayer>(throwOnError: true);
            m_componentLocomotion = Entity.FindComponent<ComponentLocomotion>(throwOnError: true);
            ValuesDictionary valuesDictionary1 = DatabaseManager.FindEntityValuesDictionary(base.Entity.ValuesDictionary.DatabaseObject.Name, throwIfNotFound: true);
            WalkSpeed = valuesDictionary1.GetValue<ValuesDictionary>("Locomotion").GetValue<float>("WalkSpeed");
            CreativeFlySpeed = valuesDictionary1.GetValue<ValuesDictionary>("Locomotion").GetValue<float>("CreativeFlySpeed");
            Speed = valuesDictionary.GetValue("Speed", 1f);
            //m_isReleased = true;
        }

        public void Update(float dt)
        {//疾跑升高体温
            PlayerInput playerInput = m_componentPlayer.ComponentInput.PlayerInput;
            if (playerInput.Move.Z > 0)
            {
                if (m_pressed && m_released)
				{
                    m_pressed = m_released = false;
                    if (Time.RealTime - m_lastForwardTime < 0.3)
                    {
                        m_isSprinting = true;
                        m_lastForwardTime = 0.0;
                    }
                    else
                    {
                        m_lastForwardTime = Time.RealTime;
                    }
                }
                m_pressed = true;
            }
            else
			{
                m_isSprinting = false;
                m_componentLocomotion.WalkSpeed = WalkSpeed;//还原速度
                m_componentLocomotion.CreativeFlySpeed = CreativeFlySpeed;
                if (m_pressed)
                    m_released = true;
            }

            if (ComponentVitalStats.Food <= 0.3f || ComponentVitalStats.Stamina <= 0.1f || m_componentPlayer.ComponentSickness.IsSick || m_componentPlayer.ComponentFlu.HasFlu || m_componentPlayer.ComponentBody.ImmersionFactor > 0.1f || m_componentPlayer.ComponentRider.Mount != null || m_componentPlayer.ComponentBody.IsSneaking)
                m_isSprinting = false;//饱食度或耐力较低，或体温大于21(20报警)，或正在生病\感冒，或浸水\骑乘\潜行时强制禁用疾跑


            if (m_isSprinting)
            {
                m_componentLocomotion.WalkSpeed = WalkSpeed * Speed;//应用速度倍数变更
                m_componentLocomotion.CreativeFlySpeed = CreativeFlySpeed * Speed;//应用创造模式飞行速度倍数变更

                float num = m_componentPlayer.ComponentLocomotion.LastWalkOrder.HasValue ? m_componentPlayer.ComponentLocomotion.LastWalkOrder.Value.Length() : 0f;
                float num3 = 1f / MathUtils.Max(m_componentPlayer.ComponentLevel.SpeedFactor, 0.75f);//等级越高，耐力消耗越少
                ComponentVitalStats.Stamina -= dt * (0.07f + 0.006f * num3) * num;//降低耐力，理论上疾跑耐力消耗速度为走路的两倍
                ComponentVitalStats.Food -= dt * 0.01f;//降低饱食度，10秒一格

                float environmentTemp = ComponentVitalStats.m_environmentTemperature;
                if (environmentTemp >= 4f)
				{//升高体温
                    ComponentVitalStats.Temperature = MathUtils.Min(21f, environmentTemp + 10f, ComponentVitalStats.Temperature + dt * 1f);
				}
            }


            if (FocalOrder.HasValue)
            {//奔跑时镜头拉远
                FppCamera fppCamera = m_componentPlayer.GameWidget.FindCamera<FppCamera>(true);
                if (m_componentPlayer.GameWidget.ActiveCamera == fppCamera)
                {
                    m_focalNum = 1f;
                    m_componentPlayer.GameWidget.ActiveCamera = new SprintDCCamera(m_componentPlayer.GameWidget);
                }
                else if (m_componentPlayer.GameWidget.ActiveCamera is SprintDCCamera)
                {
                    float min = 0.05f;
                    if (MathUtils.Abs(FocalOrder.Value - m_focalNum) <= min)
                    {
                        m_focalNum = FocalOrder.Value;
                        FocalOrder = null;
                        if (m_focalNum <= 1f)
                            m_componentPlayer.GameWidget.ActiveCamera = fppCamera;
                    }
                    else
                        m_focalNum += (FocalOrder.Value - m_focalNum) / MathUtils.Abs(FocalOrder.Value - m_focalNum) * dt * 0.75f;

                }
                else
                    FocalOrder = null;
            }

            if(m_lastIsSprinting != m_isSprinting)
			{
				if (m_isSprinting)
				{//从未疾跑切换为疾跑
                    FocalOrder = 1f / 0.8f;
                }
                else
                    FocalOrder = 1f;
            }
            m_lastIsSprinting = m_isSprinting;
        }


    }

}
